from django.db.models import Q
from rest_framework.generics import GenericAPIView, ListAPIView
from rest_framework.response import Response
from rest_framework.permissions import AllowAny

from aijia_project.utils.Error_statuscode import ErrorCode
from houses.serializers.houses import HouseSerializer, HouseSimpleSerializer, \
    HouseDetailSerializer
from houses.utils.house_detail import generate_house_detail
from houses.utils.house_search import generate_housesearch_result
from houses.utils.user_house import generate_userhouse_result
from houses.utils.str2datetime import str2datetime
from houses.models import House
from houses.utils.cache_decorator import house_search_decotator


# /api/v1.0/houses
class HouseView(GenericAPIView):
    """房源视图类"""
    serializer_class = HouseSerializer
    queryset = House.objects.all()

    # 允许所有用户访问
    permission_classes = (AllowAny,)

    def get_queryset(self, **kwargs):
        """重写了get_queryset方法，进行房屋搜索时会用到"""
        # 从查询字符串中提取参数
        aid = kwargs.get('aid')[0]
        start_day = str2datetime(kwargs.get('sd')[0])
        end_day = str2datetime(kwargs.get('ed')[0])
        # 计算租房天数
        rental_days = (end_day - start_day).days

        # 根据查询字符串中的参数找出符合要求的房源信息
        result = House.objects.filter(Q(area_id=aid) &
                                      Q(min_days__lte=rental_days) &
                                      (Q(max_days__gte=rental_days) | Q(max_days=0)))

        # 按照传入的排序规则进行排序并返回
        sort_key = kwargs.get('sk')[0]
        if sort_key == 'booking':
            return result.order_by('-order_count')
        elif sort_key == 'price-inc':
            return result.order_by('price')
        elif sort_key == 'price-des':
            return result.order_by('-price')

        # 没有传入排序规则的话就按默认的顺序返回
        return result

    @house_search_decotator
    def get(self, request):
        """房源搜索"""
        query_params = request.query_params
        queryset = self.get_queryset(**query_params)
        serializer = self.get_serializer(queryset, many=True)
        # 用自定义的辅助函数来格式化生成最后的返回结果
        search_result = generate_housesearch_result(request, serializer.data)

        return Response(search_result)

    def post(self, request):
        """添加新房源"""
        # 用序列化器来完成一些数据校验
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)

        parameters = request.data
        parameters['user_id'] = request.user.id
        facilities = parameters.pop('facility')
        house = House.objects.create(**parameters)
        house_id = house.id
        House.objects.get(id=house_id).facility.add(*facilities)

        return Response({
            "errno": ErrorCode.OK,
            "errmsg": "发布成功",
            "data": {
                "house_id": house_id
            }
        })


# /api/v1.0/user/houses
class HouseListView(GenericAPIView):
    """用户房源视图类"""
    serializer_class = HouseSerializer

    def get(self, request):
        queryset = House.objects.filter(user_id=request.user.id)
        serializer = self.get_serializer(queryset, many=True)
        # 用自定义的辅助函数来格式化生成最后的返回结果
        context = generate_userhouse_result(request, serializer.data)
        return Response(context)


# /api/v1.0/houses/index
class HouseRecommendView(GenericAPIView):
    """首页房源推荐"""
    serializer_class = HouseSimpleSerializer

    # 允许所有用户访问
    permission_classes = (AllowAny,)

    # 重写get_queryset方法来限制查询集数量为五条以内
    def get_queryset(self):
        count = 0
        result = []
        for i in House.objects.all().order_by('-order_count'):
            result.append(i)
            count += 1
            if count == 5:
                break
        return result

    def get(self, request):
        queryset = self.get_queryset()
        serializer = self.get_serializer(queryset, many=True)
        return Response({
            "data": serializer.data,
            "errmsg": "OK",
            "errno": ErrorCode.OK
        })


# /api/v1.0/houses/[int:house_id]
class HouseDetailView(GenericAPIView):
    """房源细节视图类"""
    serializer_class = HouseDetailSerializer

    # 允许所有用户访问
    permission_classes = (AllowAny,)

    def get(self, request, pk):
        house = House.objects.get(id=pk)
        serializer = self.get_serializer(house)
        # 用自定义的辅助函数来格式化生成最后的返回结果
        house_detail = generate_house_detail(request, serializer.data)
        return Response(house_detail)
